package com.locationtracker.plus.app.util

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.supervisorScope

object CommonUtil {
    fun countDownCoroutines(
        total: Int,
        scope: CoroutineScope,
        onTick: (Int) -> Unit,
        onStart: (() -> Unit)? = null,
        onFinish: (() -> Unit)? = null,
    ): Job {
        return flow {
            for (i in total downTo 0) {
                emit(i)
                delay(1000)
            }
        }.flowOn(Dispatchers.Main)
            .onStart { onStart?.invoke() }
            .onCompletion { onFinish?.invoke() }
            .onEach { onTick.invoke(it) }
            .launchIn(scope)
    }

    suspend fun compute(id: Int): Int {
        println("Compute $id started on thread: ${Thread.currentThread().name}")
        delay(1000L) // 模拟耗时计算
        println("Compute $id completed on thread: ${Thread.currentThread().name}")
        return id * 10
    }

    fun main() = runBlocking {
        println("Start: ${System.currentTimeMillis()}")
        supervisorScope {

        }


        // 协程作用域管理子协程
        coroutineScope {
            launch(Dispatchers.Main) { compute(1) }
            launch { compute(2) }
            launch { compute(3) }
        }

        // 串行任务
        val serialResult = async {
            compute(1) + compute(2)
        }

        // 并发任务
        val concurrentResults = listOf(
            async { compute(3) },
            async { compute(4) }
        ).map { it.await() }

        println("Serial Result: ${serialResult.await()}")
        println("Concurrent Results: $concurrentResults")

        println("End: ${System.currentTimeMillis()}")
    }
}